#include "user.h"
#include <QtSql>
#include <QString>
#include <QVector>

User *User::user_p = NULL;

User *User::userInstance()
{
    if(!user_p)
        user_p = new User;
    return user_p;
}

User::User()
{
}

bool User::addBuddy(QString theUser, QString theBuddy)
{
    //check if buddy exists: select username from users where username = the buddy's username
    //if the buddy exists then get id
    QSqlQuery query;
    int userId = getIdFromName(theUser);
    if( theBuddy.contains('@') ) {
    bool result =  query.exec("SELECT username from users WHERE email = '" + theBuddy + "'");
        if(result == false)
            return false; //email DNE
        else
        {
            query.next();
            theBuddy = query.value(0).toString();
        }
    }// end email query

    int buddyId = getIdFromName(theBuddy);

    if(buddyId != -1 && userId != -1)
    {
        //check if already buddy
        bool isBuddy = checkIfBuddies(userId, buddyId);
        //not buddy
        if(isBuddy == false)
        {
            bool result = query.exec("INSERT INTO buddies (user, buddy) VALUES (" + QString::number(userId) + ", " + QString::number(buddyId)+ ")");
            if(result == false)
            {
                qDebug() << "my query: " << query.lastQuery();
                qDebug() << "addBuddy: " << query.lastError();
            }
            return true;
        }
        //already buddy
        return false;
    }
    //buddy/user does not exist
    return false;
}

bool User::checkIfBuddies(int userId, int buddyId)
{
    QSqlQuery query;
    //check if already buddy
    query.exec("SELECT user FROM buddies where user = " + QString::number(userId) + " AND buddy = " + QString::number(buddyId));
    bool result = query.next();
    //not buddies
    if(query.size() == 0 || query.size() == -1 || !result)
        return false;
    //already buddies
    return true;

}

int User::getIdFromName(QString user)
{
    QSqlQuery query;
    query.exec("SELECT id FROM users WHERE username = '" + user + "'");
    bool result = query.next();
    if (result == true)
        return query.value(0).toInt();
    return -1;
}

QString User::getNameFromId(int id)
{
    qDebug() << "Got this id " << id;
    QSqlQuery query;
    query.exec("SELECT username FROM users WHERE id = " + QString::number(id));
    qDebug() << "SELECT username FROM users WHERE id = " << id;

    bool result = query.first();

    if(!result)
    {
        qDebug() << "Got an error";
    }else{
        return query.value(0).toString();
    }

    qDebug() << query.size();
    while(query.next())
    {
        qDebug() << " Name: " << query.value(0).toString();
    }
    return "";
    return "ERROR: No such user with id: " + id;
}

int User::getSocketId(QString user)
{
    QSqlQuery query;
    query.exec("SELECT socketId FROM users WHERE username = '" + user + "'");
    bool result = query.next();
    if (result == true)
        return query.value(0).toInt();
    return -1;

}

QString User::getStatus(QString user)
{
    QSqlQuery query;
    query.exec("SELECT status FROM users WHERE username = '" + user + "'");
    bool result = query.next();
    if (result == true)
        return query.value(0).toString();
    return "ERROR";
}

int User::registerNewUser(QString newUser, QString newPassword, QString email, int sid)
{

    QSqlQuery query;
    //check email
    bool emailCheck = query.exec("SELECT id FROM users WHERE email = '" + email + "'");
    if(query.size() != 0 )
    {
        qDebug() <<  "bad email: " << emailCheck;
        return -1; // -1 = bad email
    }

    bool checkUsername = query.exec("SELECT id FROM users WHERE username = '" + newUser + "'");
    if( query.size() != 0)
    {
        qDebug() << "bad username: " << newUser;
        return -1; // -2 = bad usernameSS
    }

    //INSERT INTO `messenger`.`users` (`id`, `username`, `password`, `status`) VALUES ('user2', SHA1('cookies'), 'email');
    bool result = query.exec("INSERT INTO users (`username`, `password`, `email`)"
                             "VALUES ('" + newUser + "', SHA1('" + newPassword +"'), '" + email + "')");
    if(result == false)
    {
        qDebug() << "my query: " << query.lastQuery();
        qDebug() << "register: " << query.lastError();
        return -3; // -3 = insertion fail
    }
    setSocketId(newUser, sid);
    return 1;
}

bool User::removeBuddy(QString theUser, QString theBuddy)
{
    QSqlQuery query;
    int buddyId = getIdFromName(theBuddy);
    int userId = getIdFromName(theUser);
    if(buddyId != -1 && userId != -1) //if both users exist
    {
        bool isBuddy = checkIfBuddies(userId, buddyId);
        if(isBuddy == false) //not buddies
        {
            //then do nothing, return true
            return false;
        }
        else //they are buddies; remove row
        {
            qDebug() << "sefdsg: " << "DELETE FROM buddies WHERE user = " + QString::number(userId) + " AND buddy = " + QString::number(buddyId);
            bool result = query.exec("DELETE FROM buddies WHERE user = " + QString::number(userId) + " AND buddy = " + QString::number(buddyId));
            if(result == false)
            {
                qDebug() << "my query: " << query.lastQuery();
                qDebug() << "removeBuddy: " << query.lastError();
            }
            return result;
        }
    }
    //both users to not exist
    return false;

}

void User::removeSocketId(QString user)
{
    QSqlQuery query;
    query.exec("UPDATE users SET socketId = 0 WHERE username = '" + user + "'");
}

QVector <QString> User::retrieveBuddies(QString theUser)
{
    QVector <QString> buddyVector;
    QSqlQuery query;
    //get id of user
    int userId = User::getIdFromName(theUser);
    qDebug() << "SELECT buddy FROM buddies WHERE user = " + QString::number(userId );
    //select buddy from buddies where user = user's id
    if(! query.exec("SELECT buddy FROM buddies WHERE user = " + QString::number(userId )))
    {
        qDebug() << "Debug 1: " << query.lastError();
        qDebug() << "SELECT buddy FROM buddies WHERE user = " + QString::number(userId );

    }
    qDebug() << "retrieveBuddies -- query size: " << query.size();
    while(query.next())
    {
        qDebug() << "namefromid: " << query.value(0).toInt();
        buddyVector.push_back(getNameFromId(query.value(0).toInt() ) );
        qDebug() << query.value(0).toInt();
    }

    // delete before release
    for(int i=0; i<buddyVector.size(); i++)
        qDebug() << buddyVector.at(i);
    return buddyVector;
}

QVector <QString> User::retrieveStatus(QVector <QString> buddyVector)
{
    QVector <QString> statusVector;
    QSqlQuery query;
    //qDebug() << "sfjhksf" << buddyVector.at(1);
    for(int i = 0; i < buddyVector.size(); i++)
    {
        if(! query.exec("SELECT status FROM users where username = '" + buddyVector.at(i) + "'"))
        {
            qDebug() << query.lastError();
            qDebug() << "Debug 2: " << "SELECT status FROM users where username = '" << buddyVector.at(i) << "'";

        }

        qDebug() << "retrieveStatus -- query size: " << query.size();

        query.next();
        qDebug() << "the status: " << query.value(0).toString();
        statusVector.push_back(query.value(0).toString());


    }
    return statusVector;
}

void User::setSocketId(QString user, int sid)
{
    qDebug() << sid;
    QSqlQuery query;
    //UPDATE users SET `socketId` = 3 WHERE `username` = 'sehar';
    query.exec("UPDATE users SET socketId = " + QString::number(sid) + " WHERE username = '" + user + "'");
    //query.next();
}

void User::setStatus(QString user, QString status)
{
    QSqlQuery query;
    query.exec("UPDATE users SET status = '" + status + "' WHERE username = '" + user + "'");
}

bool User::verifyEmail(QString user, QString email)
{
    QSqlQuery query;
    query.exec("SELECT user from users WHERE email = '" + email);
    bool result = query.next();
    //email does not exist
    if(query.size() == 0 || query.size() == -1 || !result)
        return false;
    //email exists
    User::addBuddy(user, (QString) query.value(0).toString());
    return true;

}

bool User::verifyLoginInfo(QString myUsername, QString myPassword, int sid)
{

    QSqlQuery query;
    query.exec("SELECT username FROM users WHERE username = '" + myUsername + "' AND password = SHA1('" + myPassword + "')");
    bool result = query.next();
    //if verfiy fails
    if(query.size() == 0 || query.size() == -1 || !result)
    {
        return result;
    }
    qDebug() << myUsername + " authentification:" << result;
    //verfify passes; set socketid

    setSocketId(myUsername, sid);
    return result;

}
